﻿package net.wangit.framework.log;

import java.util.ArrayList;
import java.util.List;

import net.wangit.User;
import net.wangit.context.ActionContext;
import net.wangit.framework.action.ActionMapping;
import net.wangit.framework.config.ProjectSettings;
import net.wangit.framework.config.UnitGroups;
import net.wangit.jdbc.DB;
import net.wangit.jdbc.DBFactory;
import net.wangit.jdbc.util.DBHelper;
import net.wangit.util.DateUtil;
import net.wangit.view.page.PageImpl;
import net.wangit.view.unit.UnitComponent;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class UserLogger {

	private static final Log log = LogFactory.getLog(UserLogger.class);
	private static List<String[]> valuesList = new ArrayList<String[]>();

	private UserLogger() {
	}

	public static synchronized void log(ActionContext ac,
			ActionMapping mapping, long cost, boolean successful) {
		String values[] = new String[14];
		try {
			setLog(ac, values, cost, successful);
			values[TAccessLog.TYPE.index] = Integer.toString(2);
			String domain = mapping.getDomain();
			values[TAccessLog.DOMAIN.index] = domain;
			String groupId = mapping.getGroupId();
			String groupName = UnitGroups.getGroupName(domain, groupId);
			values[TAccessLog.GROUP_ID.index] = groupId;
			values[TAccessLog.GROUP_NAME.index] = groupName;
			values[TAccessLog.UNIT_ID.index] = mapping.getUnitId();
			values[TAccessLog.UNIT_NAME.index] = mapping.getUnitName();
			values[TAccessLog.ELEMENT_ID.index] = mapping.getId();
			values[TAccessLog.ELEMENT_NAME.index] = mapping.getName();
			valuesList.add(values);
			check();
		} catch (Exception e) {
			log.error("log failed:", e);
		}
	}

	public static synchronized void log(ActionContext ac, PageImpl page,
			long cost, boolean successful) {
		try {
			String values[] = new String[14];
			setLog(ac, values, cost, successful);
			values[TAccessLog.TYPE.index] = Integer.toString(1);
			UnitComponent uc = page.getUnitComponent();
			String domain = uc.getDomain();
			values[TAccessLog.DOMAIN.index] = domain;
			String groupId = uc.getGroupId();
			String groupName = UnitGroups.getGroupName(domain, groupId);
			values[TAccessLog.GROUP_ID.index] = groupId;
			values[TAccessLog.GROUP_NAME.index] = groupName;
			values[TAccessLog.UNIT_ID.index] = uc.getId();
			values[TAccessLog.UNIT_NAME.index] = uc.getName();
			valuesList.add(values);
			check();
		} catch (Exception e) {
			log.error("log failed:", e);
		}
	}

	private static void setLog(ActionContext ac, String values[], long cost,
			boolean successful) {
		User user = ac.getVisitor().getUser();
		values[TAccessLog.USER_ID.index] = user.getId();
		values[TAccessLog.USER_NAME.index] = user.getName();
		values[TAccessLog.ORGANIZATION_ID.index] = user.getOrgId();
		values[TAccessLog.COST.index] = Long.toString(cost);
		values[TAccessLog.OK.index] = successful ? "1" : "0";
		values[TAccessLog.TIME.index] = DateUtil.getCurrentDatetime();
	}

	private static void check() {
		if (valuesList.size() >= ProjectSettings.instance().getLogBufferSize())
			flush();
	}

	public static synchronized void flush() {
		DB db = null;
		try {
			db = DBFactory.newDB();
			db
					.executeBatch(TAccessLog.INSERT_SQL, valuesList,
							TAccessLog.TYPES);
			valuesList = new ArrayList<String[]>();
		} catch (Exception e) {
			log.error("flush user log failed:", e);
		} finally {
			DBHelper.close(db);
		}
	}

}
